<template>
  <!-- :rules="formRules" -->
  <el-form
    ref="formRef"
    :model="formData"
  >
    {{ formData }}
    <el-row>
      <el-col
        v-for="([field, subschema], index) of schemas"
        :key="field"
        :span="subschema.span || 24"
      >
        <component
          v-if="vifParser(subschema.vif)"
          :is="getComponent(subschema.widget, subschema)" 
          v-bind="{ subschema, prevSchema: schemas[index - 1], field, props: subschema.props }"
        />
      </el-col>
    </el-row>

  </el-form>
</template>
<script>
import { getVal } from "../utils";
import { isObject, inPrimitive, hasOwnPro, isExpr, exprRegex } from "./utils";
export default {
  name: 'FormCore',
  props: {
    form: {
      type: Object,
      default: () => (null)
    },
    schema: {
      type: Object,
      required: true
    }
  },
  inject: ['$form', '$originForm'],
  provide() {
    return {
      context
    }
  },
  data() {
    return {
      // formData: this.createdForm(this.$form || {}),
      // formSchema: null,
      schemas: Object.entries(this.schema.properties)
    }
  },
  computed: {
    formData: {
      get() {
        return this.$form;
      },
      set(val) {
        this.$emit('update:form', val);
      }
    },
    context() {
      return {
        $formRef: this.$refs.formRef,
        $originForm: this.$originForm,
        $formData: this.formData,
      }
    },
    formItems() {
      return this.schemas.map(([field, subschema]) => {
        //1， 从这里找出订阅者，创建订阅实例
        Object.keys(subschema).map(property => {
          
          const value = subschema[property];
          // 如果是基本数据类型
          if(inPrimitive(subSchema.type)) {
            if(isExpr(value)) {
              subschema.property = getVal(this.context, exprRegex.exec(value)[1])
            }
          } else {
            // const typeMad = { 'array': [], 'object': {} };
            // const curFormData = this.generateFormData(subSchema, typeMad[subSchema.type], property);
            // formData[property] = curFormData;
          }
          
        });
        // return {
        //   field,
        //   subschema
        // }
      })
    },
  },
  methods: {
    parseExprOrFn(schemas, context) {
      schemas.map(([filed, subschema], index) => {
        const prevSubschema = schemas[index - 1];
        Object.keys(subschema).map(attr => {
          const value = subschema[attr];

          //判断vif
          if(hasOwnPro(subSchema, 'vif')) {
            subschema.vif = this.vifParser(subschema.vif);
          }
          // 判断velse
          if(hasOwnPro(subschema, 'velse') && prevSchema && hasOwnPro(prevSchema[1], 'vif')) {
            
          }


          // 如果是基本数据类型
          if(inPrimitive(subSchema.type)) {
            if(hasOwnPro(subSchema, 'default')) {
              this.context.$formData[property] = subSchema.default;
            }else {
              if(isExpr(value)) {
                getVal(this.context.$formData, exprRegex.exec(value)[1])
              }
            }
          } else {
            const typeMad = { 'array': [], 'object': {} };
            const curFormData = this.generateFormData(subSchema, typeMad[subSchema.type], property);
            formData[property] = curFormData;
          }
        })
      })
    },
    initFormSchema(formSchema) {
      formSchema = merge({}, formSchema);
      Object.entries(formSchema).map(([field, subschema], index) => {
        subschema = merge({}, subschema);
        // 1， 处理vif
        subschema.vif = this.vifParser(subschema.vif);
        // 2， 处理widget
        subschema.widget = this.getComponent(subschema.widget, subschema);
        // 3， 处理props
        subschema.props = this.vifParser(subschema.props);
        // 4， 处理rules
        subschema.rules = subschema.rules.map(rule => {
          
        })
      })
    },
    getComponent(widgetName, subschema) {
      if(!widgetName && subschema.type) {
        return `formily-${typeCompMap.get(subschema.type)}`;
      }
      if(typeof widgetName === 'string') {
        return `formily-${widgetName}`;
      }
      // 有可能是一个组件实例对象
      return widgetName;
    },
    vifParser(vif) {
      return this.parser(vif ?? true, this.context);
    },
    // 解析器s
    parser(expr, context) {
      return this.compiler(expr)(context);
    },
    /**
     * 编译器
     * exprOrFn = "{{ formData.name }}";
     * exprOrFn = " 1> 3"
     * exprOrFn = true;
     */
    compiler(exprOrFn) {
      // 在字符串中\本身就是一个转义字符，所以需要\\来表示\
      let exprReg = new RegExp("{{\\s*([^}]+?)\\s*}}");
      exprReg.test(exprOrFn) && (exprOrFn = exprReg.exec(exprOrFn)[1]);
      const fn = new Function('args', `with(this) {
        if(typeof ${exprOrFn} === 'function') {
          return (${exprOrFn}).apply(this, params);
        }
        return ${exprOrFn};
      }`)
      return function(context, ...args) {
        return fn.call(context || this, args);
      }
    }
  }
}
</script>